package da.metricscraft.information;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map.Entry;

import org.bukkit.entity.Player;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import da.metricscraft.MetricsCraft;
import da.metricscraft.information.MovementInformation.MoveActions;
import da.metricscraft.threads.InformationGatherer;
import da.metricscraft.threads.InformationGatherer.Xmls;
import da.metricscraft.tools.XMLWriter;
import da.metricscraft.tools.XMLWriter.XMLData;

public class PlayerInformation implements Information {
	private String name = "";
	private HashMap<PlayerDataType, Integer> data = new HashMap<PlayerDataType, Integer>();
	
	public enum PlayerDataType{
		
		LIFETIME,
		RUNTIME,
		SPRINTTIME,
		SWIMTIME,
		BOATTIME,
		CROUCHTIME,
		UNDERGROUNDTIME,
		CHUNKS_DISCOVERED, 
		CHESTS_OPENED,
		MINED(MoveActions.MINE),
		FINE_MINED(MoveActions.MINE_FINE),
		JUMPS, 
		MININGTIME, 
		BUILT(MoveActions.BUILD), 
		FITTING_ITEMS_USED, 
		DAMAGE_TAKEN(MoveActions.TAKE_DAMAGE), 
		DAMAGE_TAKEN_LAVA(MoveActions.TAKE_DAMAGE),
		DAMAGE_TAKEN_CONTACT(MoveActions.TAKE_DAMAGE),
		DAMAGE_TAKEN_ENTITY_ATTACK(MoveActions.TAKE_DAMAGE),
		DAMAGE_TAKEN_PROJECTILE(MoveActions.TAKE_DAMAGE),
		DAMAGE_TAKEN_FALL(MoveActions.TAKE_DAMAGE),
		DAMAGE_TAKEN_FIRE_TICK(MoveActions.TAKE_DAMAGE),
		DAMAGE_TAKEN_FIRE(MoveActions.TAKE_DAMAGE),
		DAMAGE_TAKEN_BLOCK_EXPLOSION(MoveActions.TAKE_DAMAGE),
		DAMAGE_TAKEN_ENTITY_EXPLOSION(MoveActions.TAKE_DAMAGE),
		DAMAGE_TAKEN_STARVATION(MoveActions.TAKE_DAMAGE),
		DAMAGE_TAKEN_DROWNING(MoveActions.TAKE_DAMAGE),
		HEALTH_REGAINED, 
		KILLS(MoveActions.KILL), 
		DEVELOP(MoveActions.DEVELOP), 
		BUTTONS_PRESSED, 
		DEVELOP_REMOVE(MoveActions.DEVELOP),
		DEATHS(MoveActions.DIE);
		private PlayerDataType(){
			moveAction = MoveActions.NONE;
		}
		private PlayerDataType(MoveActions action){
			moveAction = action;
		}
		private MoveActions moveAction = MoveActions.NONE;
		public MoveActions getMoveAction(){ return moveAction; }
		
	}
	public static interface FrequencyData{
		public Integer calculate();
		public PlayerDataType getDataType();
		public Player getPlayer();
	}
	public PlayerInformation(String name){
		this.name = name;
		MetricsCraft.log.info("[PlayerInformation][Constructor] Setting PlayerInformation name to " + name);
	}
	public HashMap<PlayerDataType, Integer> getData(){
		return data;
	}
	public void setData(PlayerDataType type, Integer value){
//		if (data.containsKey(type)){
//			MetricsCraft.log.info("[PlayerInformation][setData] Overwriting data for " + type.name() + ": " + value);
//		}else{
//			MetricsCraft.log.info("[PlayerInformation][setData] Creating new data for " + type.name() + ": " + value);
//		}
		data.put(type, value);
	}
	public void addData(PlayerDataType type, Integer value){
		if (data.containsKey(type)){
//			MetricsCraft.log.info("[PlayerInformation][addData] Overwriting data for " + type.name() + ": " + (data.get(type) + value));
			data.put(type, data.get(type) + value);
		}else{
//			MetricsCraft.log.info("[PlayerInformation][addData] Creating new data for " + type.name() + ": " + value);
			data.put(type, value);
		}
	}
	@Override
	public void process(InformationGatherer ig) {
		Document doc = ig.getXML(Xmls.PLAYER);

		HashMap<String, ArrayList<XMLData>> param = new HashMap<String, ArrayList<XMLData>>();
		for (Entry<PlayerDataType, Integer> entry : data.entrySet()){
			ArrayList<XMLData> map = new ArrayList<XMLData>();
			map.add(new XMLData("", "", entry.getValue() + ""));
			param.put(entry.getKey().name(), map);
			XMLWriter.write(doc, param, "player", name, "player", true);
		}
		
	}
	public void load(Node list){
		MetricsCraft.log.info("Loading data for player " + name);
		NodeList nodes = list.getChildNodes();
		for (int i = 0; i < nodes.getLength(); i++){
			int value = Integer.parseInt(nodes.item(i).getTextContent());
			PlayerDataType key = Enum.valueOf(PlayerDataType.class, nodes.item(i).getNodeName());
			data.put(key, value);
			MetricsCraft.log.info("-loading " + key.name() + ": " + value);
			
		}
	}
	public String getName() {
		return name;
	}
}
